<template>
    <div style="height: 100%; overflow: hidden">
		<el-row :gutter="12">
			<el-col :span="6">
				<div class="outline-container">
					<div class="outline-title"> 
						<div>文档结构图</div>
						<div>
							<SvgIcon 
								name="ele-Refresh" 
								class='cursor-pointer mr12'
								v-if="type !== 'view'"
								@click="refreshCatalogue"
								title="刷新文档结构"
							/>
							<SvgIcon 
								name="ele-View" 
								class='cursor-pointer mr12'
								v-if="type !== 'view'"
								@click="handleViewSourceCode"
								title="查看源代码"
							/>
						</div>
					</div>
					<div id="workcard_edit_catalogue"></div>
					<el-tree
						:style="`max-height: calc(${height});overflow: auto;`"
						:data="catalogue"
						:indent="12"
						:default-expand-all="true"
						:expand-on-click-node="false"
						:props="{
							children: 'children',
							label: 'label',
						}"
						@node-click="handleNodeClick"
					>
					<template #default="{ node, data }">
						<span v-if="data.id === '-1'" style="padding-left: 12px;font-weight: bold;text-align: center;width: 100%;">{{ node.label }}</span>
						<span v-else>{{ node.label }}</span>
					</template>
					</el-tree>
				</div>
			</el-col>
			<el-col :span="18">
				<div :style="{width: width}">
					<Editor
						:init="init"
						:id="tinymceId"
					/>
				</div>
			</el-col>
		</el-row>
    </div>
</template>
   
<script setup lang="ts">
import { reactive, watch, ref, nextTick, onMounted } from "vue"; //全屏
import request from '/@/utils/request';
import { Session } from '/@/utils/storage';

import tinymce from "tinymce/tinymce";
import Editor from "@tinymce/tinymce-vue";
import "tinymce/icons/default/icons";
import "tinymce/models/dom"; // 一定要引入
import "tinymce/themes/silver"; // 界面UI主题
import "tinymce/plugins/image";
import "tinymce/plugins/table";
import "tinymce/plugins/lists"; // 列表插件
import "tinymce/plugins/wordcount"; // 文字计数
import "tinymce/plugins/preview"; // 预览
import "tinymce/plugins/emoticons"; // emoji表情
import "tinymce/plugins/emoticons/js/emojis.js"; //必须引入这个文件才有表情图库
import "tinymce/plugins/code"; // 编辑源码
import "tinymce/plugins/link"; // 链接插件
import "tinymce/plugins/advlist"; //高级列表
import "tinymce/plugins/codesample"; //代码示例
import "tinymce/plugins/autoresize"; // 自动调整编辑器大小
import "tinymce/plugins/quickbars"; // 光标处快捷提示
import "tinymce/plugins/nonbreaking"; //插入不间断空格
import "tinymce/plugins/searchreplace"; //查找替换
import "tinymce/plugins/autolink"; //自动链接
import "tinymce/plugins/directionality"; //文字方向
import "tinymce/plugins/visualblocks"; //显示元素范围
import "tinymce/plugins/visualchars"; //显示不可见字符
import "tinymce/plugins/charmap"; // 特殊符号
import "tinymce/plugins/nonbreaking"; //插入不间断空格
import "tinymce/plugins/insertdatetime"; //插入日期时间
import "tinymce/plugins/importcss"; //引入自定义样式的css文件
import "tinymce/plugins/accordion"; // 可折叠数据手风琴模式
import "tinymce/plugins/anchor"; //锚点
import "tinymce/plugins/autosave"; //自动保存
import "tinymce/plugins/pagebreak"; //分页
import "tinymce/plugins/fullscreen";

const props = defineProps({
	type: {
		type: String,
		validator: (value: string) => {
			return ['edit', 'audit', 'view'].includes(value);
		}
	},
	height: {
		type: String,
		default: '100vh - 280px',
	},
	width: {
		type: String,
		default: 'calc(21cm - 26px)',
	},
	// 是否显示源码功能
	showSourceCode: {
		type: Boolean,
		default: false,
	},
	// 是否显示签名组件
	showSignature: {
		type: Boolean,
		default: false,
	},
});

const baseUrl = ref(import.meta.env.VITE_API_URL);
const electronicWorkCard = ref<any>({});
const catalogue = ref([]);
const tinymceId = ref(
	"vue-tinymce-" + +new Date() + ((Math.random() * 1000).toFixed(0) + "")
);
const isReady = ref(false);

//定义一个对象 init初始化
const init = reactive({
	selector: "#" + tinymceId.value, //富文本编辑器的id,
	language_url: '/tinymce/langs/zh_CN.js', //引入语言包文件
	language: "zh_CN",
	skin_url: "/tinymce/skins/ui/oxide", // skin路径，具体路径看自己的项目
	height: `calc(${props.height} + 50px)`,
	readonly: props.type === 'audit' || props.type === 'view',
	branding: false, // 是否禁用“Powered by TinyMCE”
	promotion: false, //去掉 upgrade
	statusbar: false, 
	menubar: "edit view insert format tools table",
	plugins: "importcss searchreplace directionality visualblocks visualchars nonbreaking wordcount advlist autolink link image lists charmap code table autosave pagebreak fullscreen",
	external_plugins: {
		'signature': '/tinymce/plugins/signature/plugin.js',
		'input': '/tinymce/plugins/input/plugin.js',
		'checkbox': '/tinymce/plugins/checkbox/plugin.js',
		'paragraph': '/tinymce/plugins/paragraph/plugin.js',
		'radio': '/tinymce/plugins/radio/plugin.js',
	},
	toolbar: props.type === 'edit' ? `undo redo fontfamily fontsize forecolor backcolor removeformat bold italic underline strikethrough lineheight outdent indent alignleft aligncenter alignright alignjustify bullist restoredraft pagebreak image table checkbox radio input ${props.showSignature ? 'signature' : ''} paragraph fullscreen` : false,
	contextmenu:'clearSignature table image copy paste cut',
	contextmenu_never_use_native: true,
	relative_urls: false,
	// 取消图片资源路径转换
	convert_urls: false,
	// 文字样式
	font_family_formats:
		'微软雅黑="微软雅黑";宋体="宋体";黑体="黑体";仿宋="仿宋";楷体="楷体";隶书="隶书";幼圆="幼圆";Andale Mono=andale mono,times; Arial=arial,helvetica,sans-serif; Arial Black=arial black,avant garde; Book Antiqua=book antiqua,palatino;Calibri; Comic Sans MS=comic sans ms,sans-serif; Courier New=courier new,courier; Georgia=georgia,palatino; Helvetica=helvetica; Impact=impact,chicago; Symbol=symbol; Tahoma=tahoma,arial,helvetica,sans-serif; Terminal=terminal,monaco; Times New Roman=times new roman,times; Trebuchet MS=trebuchet ms,geneva; Verdana=verdana,geneva; Webdings=webdings; Wingdings=wingdings,zapf dingbats', //字体
	font_size_formats: "11px 12px 14px 16px 18px 24px 36px 48px", //文字大小
	valid_elements: '*[*]',
	valid_children: '*[*]',
	image_caption: true,
	automatic_uploads: props.type === 'edit',
	file_picker_types: 'image',
	images_upload_url: '/file/upload',
	toolbar_mode: "wrap", // 工具栏模式 floating / sliding / scrolling / wrap
	advlist_bullet_styles: "circle",
	// 默认样式
	content_style: 'body { font-family:宋体,Arial,sans-serif; font-size:14px }',
	forced_root_block_attrs: {
		'style': 'font-family: 宋体;'
	},
	paste_webkit_styles: "all",
	paste_merge_formats: true,
	nonbreaking_force_tab: false,
	paste_auto_cleanup_on_paste: false,
	content_css: "/tinymce/css/custom.css", //以css文件方式自定义可编辑区域的css样式，css文件需自己创建并引入
	body_class: `${props.type}_body`,
	paste_preprocess: function(plugin, args) {
		if (args.content.indexOf("mce-checkbox") > -1
			|| args.content.indexOf("mce-textarea") > -1
			|| args.content.indexOf("mce-paragraph") > -1
			|| (args.content.indexOf("data-id") > -1 && args.content.indexOf("signature") > -1)) {
			plugin.notificationManager.open({
				text: '请勿复制系统插件内容',
				type: 'error',
				timeout: 3000,
			});
			args.content = "";
		}
	},
	setup: function (editor) {
		// tab键
		editor.on('keydown', function (evt) {
			if (evt.keyCode == 9) {
				if (evt.shiftKey) {
					editor.execCommand('Outdent');
				} else {
					editor.execCommand('Indent');
				}
				evt.preventDefault();
				evt.stopPropagation();
			}
		});

		// editor.on('NodeChange', () => {
		// 	refreshCatalogue();
        // })
	},
	init_instance_callback: (editor) => {
		editor.contentDocument.designMode = "on";
		isReady.value = true;
	},
	//图片上传
	images_upload_handler: (blobInfo, progress) => new Promise((resolve, reject) => {
		let file = blobInfo.blob();
		if (file.size / 1024 / 1024 > 200) {
			reject({
			message: "上传失败，图片大小请控制在 200M 以内",
			remove: true,
			});
		}
		const formData = new FormData();
		formData.append("file", file);
		request.post("/file/upload", formData, {
			headers: { 
				'content-type': 'multipart/form-data',
				token: `${Session.get('token') || ''}`
			},
			onUploadProgress: (progressEvent) => {
			progress(
				Math.round((progressEvent.loaded / progressEvent.total) * 100)
			);
			},
		}).then((res) => {
			resolve(`${baseUrl.value}/file/stream/${res.data[0].id}`);
		}).catch();
	}),
});

// 设置编辑器只读模式
watch(() => props.type, () => {
	nextTick(() => {
		tinymce.get(tinymceId.value)?.mode.set(props.type === 'edit' ? "design" : "readonly");
	});
},{immediate: true});

// 初始化编辑器
onMounted(() => {
	tinymce.init({});
	window.setInterval(() => {
		refreshCatalogue();
	}, 30000);
});

// 处理工卡内容
const processWorkContent = (electronicWorkCard: any) => {
	let $gknr = $(electronicWorkCard?.gknr || '');
	if (props.type !== 'edit') {
		$gknr.find("input").attr("disabled", "disabled");
		$gknr.find("textarea").attr("disabled", "disabled");
		$gknr.find("input:checkbox:checked").replaceWith('<span class="mce-checkbox" style="font-family: Wingdings;font-size: 18px;margin: 0 2.4px;">þ</span>');
		$gknr.find("input:checkbox:not(:checked)").replaceWith('<span class="mce-checkbox" style="font-family: 宋体;font-weight: bold;font-size: 18px;margin: 0 1.4px;">□</span>');
	}
	// @ts-ignore
	let $div = $("<div></div>");
	$div.append($gknr);
	return $div.html();
}

// 设置值
const handleSetElectronicWorkCard = (res: any) => {
	setTimeout(() => {
		electronicWorkCard.value = res || {};
		tinymce.get(tinymceId.value)?.setContent(processWorkContent(electronicWorkCard.value));
		refreshCatalogue();	
	}, isReady.value ? 0 : 500)
};

// 获取值
const handleGetElectronicWorkCard = (editor?: any) => {
	editor = editor || tinymce.get(tinymceId.value);
	const users = [] as any[];
	let gknr = editor?.getContent();
	let gzzbs = 0;
	let jczbs = 0;
	var $container = $(editor?.contentDocument);
	$container.find(".signature").each((i, obj) => {
		var $signature = $(obj);
		var type = $signature.attr("data-type");
		if (type === "1") {
			gzzbs = 1;
		}
		if (type === "2") {
			jczbs = 1;
		}
	})

	return {
		...electronicWorkCard.value,
		zt: null,
		gknr: gknr,
		users: users,
		gzzbs: gzzbs,
		jczbs: jczbs,
	}
};

// 刷新目录
const refreshCatalogue = () => {
	var editor = tinymce.get(tinymceId.value);
	var rootId = "-1";
	var root = {"id" : rootId, "label" : "工作内容", children: [] as any[]};
	if (editor) {
		var $html = $(editor.contentDocument);
		var level1, level2, level3, level4;
		$html.find(".mce-paragraph").each((i, obj) => {
			var $obj = $(obj);
			if ($obj.parent().is(".mce-offscreen-selection")) {
				return true;
			}
			var id = $obj.attr("id");
			var level = $obj.attr("data-mce-level");
			var text = $obj.text().replace("{*","").replace("*}","");
			var levelObj = {"id" : id, "label" : text, children: []};
			if ($obj.text() && ["1", "2", "3"].includes(level)) {
				if (level === "1") {
					level1 = levelObj;
					level2 = null;
					level3 = null;
					level4 = null;
					root.children.push(levelObj);
				} else if (level === "2") {
					level2 = levelObj;
					level3 = null;
					level4 = null;
					(level1 || root).children.push(levelObj);
				} else if (level === "3") {
					level3 = levelObj;
					level4 = null;
					(level2 || level1 || root).children.push(levelObj);
				} else if (level === "4") {
					level4 = levelObj;
					(level3 || level2 || level1 || root).children.push(levelObj);
				} else if (level === "5") {
					(level4 || level3 || level2 || level1 || root).children.push(levelObj);
				}
			}
		});
	}
	catalogue.value = [root];
}

const handleNodeClick = (node: any) => {
	var dom = tinymce.get(tinymceId.value)?.dom.get(node.id);
	dom && dom.scrollIntoView({
		behavior: 'smooth',
	});
}

const handleViewSourceCode = () => {
	// tinymce.get(tinymceId.value)?.execCommand('mceCodeEditor');
	const editor = tinymce.get(tinymceId.value);
	const editorContent = editor?.getContent({ source_view: true });
	editor?.windowManager.open({
		title: 'Source Code',
		size: 'large',
		body: {
		type: 'panel',
		items: [{
			type: 'textarea',
			name: 'code'
			}]
		},
		buttons: [
		{
			type: 'cancel',
			name: 'cancel',
			text: 'Cancel'
		},
		{
			type: 'submit',
			name: 'copy',
			text: 'Copy',
			primary: true
		}
		],
		initialData: { code: editorContent },
		onSubmit: api => {
			navigator.clipboard.writeText(editorContent).then(function() {
				editor.notificationManager.open({
					text: '已复制电子工卡内容到剪贴板',
					type: 'info',
					timeout: 3000,
				});
			}, function(err) {
				editor.notificationManager.open({
					text: 'Failed to copy text to clipboard: ' + err,
					type: 'error',
					timeout: 3000,
				});
			});
          api.close();
        }
	});
	$(".tox-dialog__footer-end button").removeAttr("disabled");
}

const handleSetDisabled = () => {
	tinymce.get(tinymceId.value)?.mode.set("readonly");
};

// eslint-disable-next-line no-undef
defineExpose({
	handleSetElectronicWorkCard,
	handleGetElectronicWorkCard,
	handleSetDisabled,
});
</script>

<style lang="scss">
.tox-tinymce-aux{z-index:99999 !important;}
.tinymce.ui.FloatPanel{z-Index: 99;}
</style>
<style scoped lang="scss">
	.outline-container {
		border: 2px solid #eeeeee;
		border-radius: 10px;
		height: 100%;
		background-color: #ffffff;
	}
	.outline-title {
		height: 47.5px;
		font-size: 14px;
		line-height: 39px;
		padding-left: 5px;
		border-bottom: 1px solid #e3e3e3;
		display: flex;
		align-items: center;
		justify-content: space-between;
	}
	.tox-tinymce-aux .tox-pop {
		display: none;
	}
	:deep(.el-tree-node__expand-icon.expanded) {
		display: none;
	}
	:deep(.el-tree-node__expand-icon.is-leaf) {
		display: none;
	}
</style>